using UnityEngine;
using System;

namespace MyTools{
    
public class Cooldown{
    float nowTime;
    float maxTime;
    float timeRate;

    int nowCapacity; //冷却几次
    int maxCapacity;
    
    //CoolDown的第一种用法, 冷却时间
    /*Example
        在Start中初始化
        Cooldown cd = new Cooldown(3f);
        在Update中
        cd.Update(Time.deltaTime);
        在需要检查是否冷却时Check
        if(cd.Check()){
            //do something
        }
        在使用掉用次数时
        cd.Used();
    */
    
    public Cooldown(float maxTime, int maxCapacity = 1, float timeRate = 1){
        this.maxTime = maxTime;
        this.nowTime = 0;

        this.timeRate = 1;
        this.nowCapacity = maxCapacity;
        this.maxCapacity = maxCapacity;
    }

    public bool Check(){
        return nowCapacity > 0;
    }

    public bool Used(){
        if(nowCapacity>0){
            nowCapacity--;
            return true;
        }
        return false;
    }

    public void Update(float deltaTime){
        if(nowCapacity < maxCapacity){
            nowTime += deltaTime * timeRate;
            if(nowTime > maxTime){
                nowCapacity += 1;
                nowTime = 0;
            }
        }
    }

    //设置冷却时间速率
    public void SetTimeRate(float timeRate){
        this.timeRate = timeRate;
    }

    //立即回复一个capacity
    public void CooldownImidiately(){
        if(nowCapacity<maxCapacity){
            nowCapacity+=1;
            if(nowCapacity == maxCapacity) nowTime = 0;
        }
    }



    //CoolDown的第二种用法, 倒计时结束后执行回调
    /*Example
    public class ExampleUsage : MonoBehaviour
{
    public GameObject goSignal;
    private Cooldown destroyCooldown;

    void Start()
    {
        destroyCooldown = new Cooldown(5f, () => {
            goSignal.SetActive(false);
        });

        // Start the cooldown
        destroyCooldown.StartCooldown();
    }

    void Update()
    {
        // For demonstration purposes, restart the cooldown by pressing space
        if (Input.GetKeyDown(KeyCode.Space))
        {
            destroyCooldown.StartCooldown();
        }
    }
}
    */
    private Action callback;
    private bool bIsCoolingDown;
    public Cooldown(float cooldownTime, Action callback){
        maxTime = cooldownTime;
        this.callback = callback;
        bIsCoolingDown = false;
    }

    public void StartCoolDown(){
        if(!bIsCoolingDown){
            bIsCoolingDown = true;
            nowTime = maxTime;
            CoroutineManager.Instance.StartCoroutine(CooldownRoutine());
        }
    }

    private System.Collections.IEnumerator CooldownRoutine(){
        while(nowTime>0){
            nowTime -= Time.deltaTime;
            yield return null;
        }
        bIsCoolingDown = false;
        callback?.Invoke();
    }
}

}